// Created by plusminus on 9:22:20 PM - Mar 5, 2009
package com.zj.osm.view.map.offline.test;

import android.os.Environment;
import android.util.Log;

import com.blankj.utilcode.util.FileUtils;
import com.zj.osm.view.map.offline.test.adt.OSMTileInfo;
import com.zj.osm.view.map.offline.test.download.DownloadManager;
import com.zj.osm.view.map.offline.test.util.DbCreator;
import com.zj.osm.view.map.offline.test.util.FolderZipper;
import com.zj.osm.view.map.offline.test.util.Util;

import org.osmdroid.util.GEMFFile;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class OSMMapTilePackager {

    public interface ProgressNotification {

        void updateProgress(String msg);
    }

    public static void execute(final String pServerURL, final String pDestinationFile,
                               final String pTempFolder, final int pThreadCount, final String pFileAppendix,
                               final int pMinZoom, final int pMaxZoom, final double pNorth, final double pSouth,
                               final double pEast, final double pWest, final ProgressNotification callbackNotification) {
        System.out.println("---------------------------");
        if (pServerURL != null) {
            runDownloading(pServerURL, pTempFolder, pThreadCount, pFileAppendix, pMinZoom, pMaxZoom, pNorth, pSouth, pEast, pWest, callbackNotification);
        } else {
            System.out.println("using temporary directory content");
        }
        System.out.println("---------------------------");
        if (callbackNotification != null) {
            callbackNotification.updateProgress("Download complete, creating archive");
        }
        if (pDestinationFile.endsWith(".zip")) {
            runZipToFile(pTempFolder, pDestinationFile);
        } else if (pDestinationFile.endsWith(".gemf")) {
            runCreateGEMFFile(pTempFolder, pDestinationFile);
        } else {
            runCreateDb(pTempFolder, pDestinationFile);
        }

        System.out.println("---------------------------");
        String tempFolder = Environment.getExternalStorageDirectory().getPath() + "/Mapnik";
        // 清理下载的中间图片文件
        if (FileUtils.listFilesInDir(tempFolder).size() > 0)
            FileUtils.deleteAllInDir(tempFolder);

        if (callbackNotification != null) {
            callbackNotification.updateProgress("Arching complete, deleting temp files");
        }

        System.out.println("---------------------------");
    }


    private static void runCreateGEMFFile(final String pTempFolder, final String pDestinationFile) {
        try {
            System.out.println("Creating GEMF archive from " + pTempFolder + " to " + pDestinationFile + " ...");
            final List<File> sourceFolders = new ArrayList<File>();
            sourceFolders.add(new File(pTempFolder));
            final GEMFFile file = new GEMFFile(pDestinationFile, sourceFolders);
            System.out.println(" done.");
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }

    private static void runZipToFile(final String pTempFolder, final String pDestinationFile) {
        try {
            System.out.print("Zipping files to " + pDestinationFile + " ...");
            FolderZipper.zipFolderToFile(new File(pDestinationFile), new File(pTempFolder));
            System.out.println(" done.");
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }

    private static void runCreateDb(final String pTempFolder, final String pDestinationFile) {
        try {
            System.out.print("Putting files into db : " + pDestinationFile + " ...");
            DbCreator.putFolderToDb(new File(pDestinationFile), new File(pTempFolder));
            System.out.println(" done.");
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }


    private static void runDownloading(final String pBaseURL, final String pTempFolder, final int pThreadCount,
                                       final String pFileAppendix, final int pMinZoom, final int pMaxZoom, final double pNorth,
                                       final double pSouth, final double pEast, final double pWest, final ProgressNotification callbackNotification) {
        final String pTempBaseURL = pTempFolder
                + File.separator + "%d"
                + File.separator + "%d"
                + File.separator + "%d"
                + ".jpeg"
                + pFileAppendix
                .replace(File.separator + File.separator, File.separator);

        //Log.e("TAG", "runDownloading: " + pTempBaseURL);
        final DownloadManager dm = new DownloadManager(pBaseURL, pTempBaseURL, pThreadCount);

        /* For each zoomLevel. */
        for (int z = pMinZoom; z <= pMaxZoom; z++) {
            final OSMTileInfo upperLeft = Util.getMapTileFromCoordinates(pNorth, pWest, z);
            final OSMTileInfo lowerRight = Util.getMapTileFromCoordinates(pSouth, pEast, z);

            System.out.print("ZoomLevel: " + z + " ");

            for (int x = upperLeft.x; x <= lowerRight.x; x++) {
                for (int y = upperLeft.y; y <= lowerRight.y; y++) {
//                         if (callbackNotification != null) {
//                              callbackNotification.updateProgress("Downloading " + z + "/" + x + "/" + y);
//                         }
                    dm.add(new OSMTileInfo(x, y, z), callbackNotification);
                }
            }
            try {
                dm.waitEmpty();
                System.out.println(" done.");
            } catch (final InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            System.out.print("Awaiting termination of all threads ...");
            dm.waitFinished();
            System.out.println(" done.");
        } catch (final InterruptedException e) {
            e.printStackTrace();
        }
    }

}
